#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<unistd.h>
#include<ctype.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
using namespace std;
#define commandline_size 1024
#define identify "$"
#define format "%s@%s:%s# "

char * strdivide[1024];
int g_argc=0;

//重定向
#define NONE 0
#define READ 1
#define WRITE_EMPITY 2
#define WRITE_APEND 3

int redir=0;
string filename;

const char*  Getuser()
{
    const char* ret=getenv("USER");
    return ret==NULL?"NONE":ret;

}

const char*Gethostname()
{
    char hostname[256];
    //const char*ret=getenv("HOSTNAME");
   int ret=  gethostname(hostname,sizeof(hostname));
    //return ret==0?(const char*)hostname :NULL;
    string s1(hostname);
    return ret==0?s1.c_str() :NULL;

}
//当前工作路径
char cwd[1024];
string GetPwd()
{
   // const char*ret1 =getenv("PWD");
  const char*ret1=getcwd(cwd,sizeof(cwd));
    string ret(ret1);
    string s1="/home/lbl";
    string s2="~";
    int pos=ret.find(s1);
    if(pos!=-1)
      {
        ret.replace(pos,s1.size(),s2);
     }
     return ret;
   //
   //const char*ret=getenv("PWD");
   //return ret;
}


void Makecommmandline(char command[],int size)
{
    snprintf(command,size,format,Getuser(),Gethostname(),GetPwd().c_str());


}
void Printcommandline()
{
    char str[1024];
    Makecommmandline(str,sizeof(str));
    printf("%s",str);
    fflush(stdout);

}

void Inputcommand(char command[],int size)
{

        char*ret=fgets(command,size,stdin);
        command[strlen(command)-1]=0;
}

#define mark " "
void Dividecommandline(char command[])
{       
    g_argc=0;
    strdivide[0]=strtok(command,mark);
    for(int i=1;strdivide[i-1]!=NULL;i++)
    {
        g_argc++;

        strdivide[i]=strtok(NULL,mark);
    }

}

void PrintDcommand(char**str)
{
    for(int i=0;str[i]!=NULL;i++)
    {
        printf("%s ",str[i]);
    }
    printf("\n");

}

void Excutecommand(char**str)
{
    
    int pid=fork();//创建子进程来执行命令
    if(pid==0)
    {
        if(redir==READ)
        {

            int fd=open(filename.c_str(),O_RDWR);
            if(fd==-1) exit(1);
            dup2(fd,0);
        }
       else if(redir==WRITE_EMPITY)
        {
           // printf("清空写\n");
            int fd=open(filename.c_str(),O_CREAT|O_WRONLY|O_TRUNC,0666);
            if(fd==-1) exit(1);
            dup2(fd,1);
        }
       else if(redir==WRITE_APEND)
        {

            int fd=open(filename.c_str(),O_CREAT|O_WRONLY|O_APPEND,0666);
            if(fd==-1) exit(1);
            dup2(fd,1);
        }
       else
       {

       }
        execvp(str[0],str);
    }

   if(! waitpid(-1,NULL,0)==pid) exit(-1);
   redir=0;

    

}
string last_path;
bool shell_builtin(char**str)//内鉴命令判断
{
    string s=str[0];

    if(s=="cd")
    {
        if(g_argc==1)
        {
            chdir(getenv("HOME"));
            return true;
        }
        string s2=str[1];
        if(s2=="~")
        {
            chdir(getenv("HOME"));
        }
        else if(s2=="..")//上级目录
        {
           //string s3=GetPwd();
           //cout<<s3<<endl;
           //int pos=s3.rfind('/');
           //cout<<++pos<<endl;
           //chdir(s3.substr(0,pos).c_str());
           //cout<<s3.substr(0,pos)<<endl;
           string pwd(cwd);
           int pos=pwd.rfind("/");
           chdir(pwd.substr(0,pos+1).c_str());


        }
        else if(s2=="-")
        {
            if(last_path.size()==0)
            {
                cout<<"cd: OLDPWD is not set!"<<endl;
            }
            else
            {

                chdir(last_path.c_str());
            }


        }
        else
        {
            last_path=cwd;//记录当前路径
            chdir(str[1]);//切换路径
        }

        return true;        
    
    }
    else
    {
        return 0;
    }
}

void Skip_space(char com[], int&end)
{
    while(isspace(com[end]))
    {
        end++;
    }

}
void test_redir(char com[])
{
    int start=0;
    int end=strlen(com)-1;//最后元素的下标
    while(end>start)
    {
        if(com[end]=='<')
        {
            com[end++]=0;//从后往前遍历，设置\0截断字符串
            Skip_space(com,end);//当end结束后则为文件的开始
            redir=1;
            filename=com+end;//文件就找到了 就行如 /log.txt
            break;
        }
        else if(com[end]=='>')
        {
           // printf("我有>\n");
            if(com[end-1]=='<')//追加
            {

            com[end++]=0;//从后往前遍历，设置\0截断字符串
            Skip_space(com,end);//当end结束后则为文件的开始
            redir=3;
            filename=com+end;//文件就找到了 就行如 /log.txt

            }
            else
            {

            com[end++]=0;//从后往前遍历，设置\0截断字符串
            Skip_space(com,end);//当end结束后则为文件的开始
            redir=2;
            filename=com+end;//文件就找到了 就行如 /log.txt
            }
            break;

        }
        else
        {
            end--;
        }


    }

}

int main()
{
    while(1)
    {
        Printcommandline();//打印命令提示符
        char commandline[commandline_size];
        Inputcommand(commandline,sizeof(commandline));//输入命令
         //解释命令行
         //PrintDcommand(strdivide);
         test_redir(commandline);//判断是否为重定向，并设置redir
        Dividecommandline(commandline);
     //   printf("%d\n",g_argc);
        if(shell_builtin(strdivide))//内置命令
            continue;
         Excutecommand(strdivide);



   
        //commandline[strlen(commandline)-1]=0;
   
       // printf("echo %s",commandline );
    }
    return 0;
}
